/*
 * Copyright 2020-2030 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitee.minimalismstyle.fresh.common.core.conversion

import com.gitee.minimalismstyle.fresh.common.core.exception.MessageException
import java.math.BigDecimal
import java.util.*
import kotlin.reflect.KClass

/**
 * 类型转换器工厂
 * @author maoxiaodong
 */
object TypeConversionFactory {
    val typeConversionMapping = mutableMapOf<String, MutableMap<String, TypeConversion<*, *>>>(
        String::class.java.name to
                mutableMapOf(
                    "Int" to StringToIntTypeConversion(),
                    "String" to AnyToStringTypeConversion(),
                    "Boolean" to StringToBooleanTypeConversion(),
                    "Date" to StringToDateTypeConversion(),
                    "BigDecimal" to StringToBigDecimalTypeConversion(),
                    Int::class.java.name to StringToIntTypeConversion(),
                    String::class.java.name to AnyToStringTypeConversion(),
                    Boolean::class.java.name to StringToBooleanTypeConversion(),
                    Date::class.java.name to StringToDateTypeConversion(),
                    BigDecimal::class.java.name to StringToBigDecimalTypeConversion()
                )
    )

    /**
     * 获取类型转换器
     * @param sourceType 来源类型
     * @param targetType 目标类型
     * @return 返回类型转换器
     */
    fun get(sourceType: KClass<*>, targetType: KClass<*>): TypeConversion<*, *>{
        return get(sourceType.java, targetType.java)
    }

    /**
     * 获取类型转换器
     * @param sourceType 来源类型
     * @param targetType 目标类型
     * @return 返回类型转换器
     */
    fun get(sourceType: Class<*>, targetType: Class<*>): TypeConversion<*, *>{
        return get(sourceType.name, targetType.name)
    }

    /**
     * 获取类型转换器
     * @param sourceType 来源类型
     * @param targetType 目标类型
     * @return 返回类型转换器
     */
    fun get(sourceType: String, targetType: String): TypeConversion<*, *>{
        return if(!typeConversionMapping.containsKey(sourceType)){
            throw MessageException(message = "请定义${sourceType}到${targetType}的转换器")
        }else if(!typeConversionMapping[sourceType]!!.containsKey(targetType)){
            throw MessageException(message = "请定义${sourceType}到${targetType}的转换器")
        }else{
            typeConversionMapping[sourceType]!![targetType]!!
        }

    }

    /**
     * 添加类型转换器
     * @param sourceType 来源类型
     * @param targetType 目标类型
     * @param typeConversion 类型转换器
     */
    fun addTypeConversion(sourceType: String, targetType: String, typeConversion: TypeConversion<*, *>){
        if(typeConversionMapping.containsKey(sourceType)){
            typeConversionMapping[sourceType]!!.put(targetType, typeConversion)
        }else{
            typeConversionMapping.put(sourceType, mutableMapOf(targetType to typeConversion))
        }

    }
}